home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
DEMON
/
GNU
/
PDMake
/
c
/
make
< prev
next >
Wrap
Text File
|
1995-04-09
|
6KB
|
274 lines
/* > C.Make
*
* $Id: c.make 1.8 95/07/15 13:20:02 root Exp $
*
* $Log: c.make $
* Revision 1.8 95/07/15 13:20:02 root
* root, go away
*
* Revision 1.7 95/07/15 13:18:11 root
* Added filename editing in all system() , modtime & touch calls
* so RISCOS names work.
*
* Revision 1.6 95/04/19 22:51:45 root
* When releasing, get the code right ??
*
* Revision 1.5 95/04/19 22:44:39 root
* Checked in for release
*
* Revision 1.4 95/04/19 22:34:59 root
* Altered the system[] call to operate
* correctly on error return
*
* Revision 1.3 95/04/18 21:48:29 root
* *** empty log message ***
*
* Revision 1.2 95/04/18 21:42:07 root
* Tidied for release
*
*
* Do the actual making for make
*/
#include "unistd.h"
#include "h.h"
/* Used to get os_file for 'touch' */
#include <sys/os.h>
/*
* Exec a shell that returns exit status correctly (/bin/esh).
* The standard EON shell returns the process number of the last
* async command, used by the debugger (ugg).
* [exec on eon is like a fork+exec on unix]
*/
void dosh(char *string,bool ignore)
{
int rc = 0;
char * ret ;
char * cmdline;
/* need to strip the command line down into the shortest form possible */
cmdline = do_RO_names(string ); /* and do RISCOS path editing */
rc = system (cmdline);
/* Unless ignoring return codes, bomb on non-zero return */
if (!ignore && rc )
exit(rc);
}
/*
* Do commands to make a target
*/
void
docmds1(struct name *np, struct line *lp)
{
bool ssilent;
bool signore;
register char * q;
register char * p;
register struct cmd * cp;
for (cp =(lp->l_cmd); cp!=NULL ; cp = (cp->c_next))
{
strcpy(str1, cp->c_cmd);
expand(str1);
q = str1;
ssilent = silent;
signore = ignore;
while ((*q == '@') || (*q == '-'))
{
if (*q == '@') /* Specific silent */
ssilent = TRUE;
else /* Specific ignore */
signore = TRUE;
q++; /* Not part of the command */
}
if (!domake)
ssilent = 0; /* shut up if making */
/*
if (!ssilent)
fputs("Need to do: ", stdout);
*/
for (p=q; *p; p++)
{
if (*p == '\n' && p[1] != '\0')
{
*p = ' ';
if (!ssilent)
fputs("\\\n", stdout);
}
else if (!ssilent)
putchar(*p);
}
if (!ssilent)
putchar('\n');
if (domake)
{ /* Get the shell to execute it */
dosh(q,signore );
}
}
}
void
docmds(struct name *np)
{
register struct line * lp;
for (lp = np->n_line; lp; lp = lp->l_next)
docmds1(np, lp);
}
/*
* Get the modification time of a file. If the first
* doesn't exist, it's modtime is set to 0.
*/
void
modtime(struct name * np)
{
char * RO_name;
struct stat StatBuf;
StatBuf.st_mode = 0L; /* zero mode so you can tell that its a file */
RO_name = do_RO_names(np->n_name);
stat (RO_name, &StatBuf); /* Unix Stat */
if ((StatBuf.st_mode & S_IFREG)==0) /* IFREG regular file ? man 5 stat ?*/
np->n_time = 0L;
else
np->n_time = StatBuf.st_ctime;
/* printf("File is '%s' : mode %010o time: %d\n",
RO_name,StatBuf.st_mode,np->n_time);
*/
}
/*
* Update the mod time of a file to now.
* RISCOS specific routine as there isnt one in UnixLib.
*/
void
touch(struct name *np)
{
char * RO_name;
if (!domake || !silent)
printf(" touch(%s)\n", np->n_name);
if (domake)
{
RO_name = do_RO_names(np->n_name);
os_file(9,RO_name,0); /* set the stamp on the file */
}
}
void make1(struct name *np, struct line * lp,struct depend * qdp);
/*
* Recursive routine to make a target.
*/
int make(struct name *np, int level)
{
register struct depend * dp;
register struct line * lp;
register struct depend * qdp;
time_t dtime;
bool didsomething;
didsomething = 0;
dtime = 1;
#ifdef debug
printf ("Make : %s\n",np->n_name);
#endif
if (np->n_flag & N_DONE)
return 0;
if (!np->n_time)
modtime(np); /* Gets modtime of this file */
if (rules)
{
for (lp = np->n_line; lp; lp = lp->l_next)
if (lp->l_cmd)
break;
if (!lp)
dyndep(np);
}
if (!(np->n_flag & N_TARG) && np->n_time == 0L)
fatal("Don't know how to make %s", np->n_name);
for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next)
{
for (dp = lp->l_dep; dp; dp = dp->d_next)
{
make(dp->d_name, level+1);
if (np->n_time < dp->d_name->n_time)
qdp = newdep(dp->d_name, qdp);
dtime = max(dtime, dp->d_name->n_time);
}
if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
{
make1(np, lp, qdp); /* free()'s qdp */
dtime = 1;
qdp = (struct depend *)0;
didsomething++;
}
}
np->n_flag |= N_DONE;
if (quest)
{
long t;
t = np->n_time;
time(&np->n_time);
return t < dtime;
}
else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
{
make1(np, (struct line *)0, qdp); /* free()'s qdp */
time(&np->n_time);
}
else if (level == 0 && !didsomething)
printf(MYNAME": '%s' is up to date\n", np->n_name);
return 0;
}
void
make1(struct name *np, struct line * lp,struct depend * qdp)
{
register struct depend * dp;
if (dotouch)
touch(np);
else
{
strcpy(str1, "");
for (dp = qdp; dp; dp = qdp)
{
if (strlen(str1))
strcat(str1, " ");
strcat(str1, dp->d_name->n_name);
qdp = dp->d_next;
free(dp);
}
setmacro("?", str1);
setmacro("@", np->n_name);
if (lp) /* lp set if doing a :: rule */
docmds1(np, lp);
else
docmds(np);
}
}